﻿using NPOI.SS.Formula.Functions;
using NPOI.Util;
using OSSUtility.Communicate;
using OSSUtility.Device;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vlc.DotNet.Core.Interops.Signatures;

namespace Ozone.Device
{

    /// <summary>
    /// 馏分收集器
    /// </summary>
    public class DevFractionCollector : DevBase
    {
        public DevFractionCollector(int CommType, string FSrvIP, int FPort) : base(CommType, FSrvIP, FPort)
        {

        }
        /// <summary>
        /// 设置起始位置
        /// </summary>
        /// <param name="Number"></param>
        /// <returns></returns>
        public bool SetStarLocation(int Number)
        {

            bool temperature = false;

            //例如：起始位置1
            //26 31 34 30 30 31  A1 32
            try
            {
                string positionStr = Number.ToString("D2");
                byte[] dataToSend = new byte[6];
                dataToSend[0] = 0x26;
                dataToSend[1] = 0x31;
                dataToSend[2] = 0x34;
                dataToSend[3] = 0x30;
                dataToSend[4] = (byte)positionStr[0];
                dataToSend[5] = (byte)positionStr[1];
                // 计算CRC16-Modbus
                ushort crc = CalculateCRC16Modbus(dataToSend);

                // 添加CRC到数据末尾
                byte[] commandWithCRC = new byte[dataToSend.Length + 2];
                Array.Copy(dataToSend, commandWithCRC, dataToSend.Length);
                commandWithCRC[dataToSend.Length] = (byte)(crc & 0xFF);
                commandWithCRC[dataToSend.Length + 1] = (byte)((crc >> 8) & 0xFF);

                byte[] byteRcv = session_.sendAndReadByteLock(commandWithCRC.ToArray(), 3000);
                if (byteRcv != null)
                {
                    //发送和接受参数一直代表设置成功
                    if (commandWithCRC.SequenceEqual(byteRcv))
                    {
                        temperature = true;
                    }
                    else
                    {
                        temperature = false;
                    }
                }
            }
            catch (Exception ex)
            {

                temperature = false;
            }



            return temperature;

        }


        /// <summary>
        /// 设置结束位置
        /// </summary>
        /// <param name="Number"></param>
        /// <returns></returns>
        public bool SetEndLocation(int Number)
        {

            bool temperature = false;

            //例如：终止位置20
            //26 31 35 30 32 30 60 6E
            try
            {
                string positionStr = Number.ToString("D2");
                byte[] dataToSend = new byte[6];
                dataToSend[0] = 0x26;
                dataToSend[1] = 0x31;
                dataToSend[2] = 0x35;
                dataToSend[3] = 0x30;
                dataToSend[4] = (byte)positionStr[0];
                dataToSend[5] = (byte)positionStr[1];
                // 计算CRC16-Modbus
                ushort crc = CalculateCRC16Modbus(dataToSend);

                // 添加CRC到数据末尾
                byte[] commandWithCRC = new byte[dataToSend.Length + 2];
                Array.Copy(dataToSend, commandWithCRC, dataToSend.Length);
                commandWithCRC[dataToSend.Length] = (byte)(crc & 0xFF);
                commandWithCRC[dataToSend.Length + 1] = (byte)((crc >> 8) & 0xFF);

                byte[] byteRcv = session_.sendAndReadByteLock(commandWithCRC.ToArray(), 3000);
                //发送和接受参数一直代表设置成功
                if (commandWithCRC.SequenceEqual(byteRcv))
                {
                    temperature = true;
                }
                else
                {
                    temperature = false;
                }
            }
            catch (Exception ex)
            {

                temperature = false;
            }
            return temperature;

        }

        /// <summary>
        ///  设置流速
        /// </summary>
        /// <param name="Number"></param>
        /// <returns></returns>
        public bool SetFlowLocation(int Number)
        {

            bool temperature = false;
            //例如：流速100
            //26 31 31 31 30 30 31 FE
            try
            {
                string positionStr = Number.ToString("D3");
                byte[] dataToSend = new byte[6];
                dataToSend[0] = 0x26;
                dataToSend[1] = 0x31;
                dataToSend[2] = 0x31;
                dataToSend[3] = (byte)positionStr[0];
                dataToSend[4] = (byte)positionStr[1];
                dataToSend[5] = (byte)positionStr[2];
                // 计算CRC16-Modbus
                ushort crc = CalculateCRC16Modbus(dataToSend);

                // 添加CRC到数据末尾
                byte[] commandWithCRC = new byte[dataToSend.Length + 2];
                Array.Copy(dataToSend, commandWithCRC, dataToSend.Length);
                commandWithCRC[dataToSend.Length] = (byte)(crc & 0xFF);
                commandWithCRC[dataToSend.Length + 1] = (byte)((crc >> 8) & 0xFF);

                byte[] byteRcv = session_.sendAndReadByteLock(commandWithCRC.ToArray(), 3000);
                //发送和接受参数一直代表设置成功
                if (commandWithCRC.SequenceEqual(byteRcv))
                {
                    temperature = true;
                }
                else
                {
                    temperature = false;
                }
            }
            catch (Exception ex)
            {

                throw;
            }

            return temperature;

        }


        /// <summary>
        /// 设置容量
        /// </summary>
        /// <param name="Number"></param>
        /// <returns></returns>
        public bool SetCapacityLocation(int Number)
        {

            bool temperature = false;


            //例如：容量80
            //26 31 38 30 38 30 64 62
            try
            {
                string positionStr = Number.ToString("D2");
                byte[] dataToSend = new byte[6];
                dataToSend[0] = 0x26;
                dataToSend[1] = 0x31;
                dataToSend[2] = 0x38;
                dataToSend[3] = 0x30;
                dataToSend[4] = (byte)positionStr[0];
                dataToSend[5] = (byte)positionStr[1];
                // 计算CRC16-Modbus
                ushort crc = CalculateCRC16Modbus(dataToSend);

                // 添加CRC到数据末尾
                byte[] commandWithCRC = new byte[dataToSend.Length + 2];
                Array.Copy(dataToSend, commandWithCRC, dataToSend.Length);
                commandWithCRC[dataToSend.Length] = (byte)(crc & 0xFF);
                commandWithCRC[dataToSend.Length + 1] = (byte)((crc >> 8) & 0xFF);

                byte[] byteRcv = session_.sendAndReadByteLock(commandWithCRC.ToArray(), 3000);
                //发送和接受参数一直代表设置成功
                if (commandWithCRC.SequenceEqual(byteRcv))
                {
                    temperature = true;
                }
                else
                {
                    temperature = false;
                }
            }
            catch (Exception ex)
            {

                throw;
            }

            return temperature;

        }


        /// <summary>
        /// 设置高度
        /// </summary>
        /// <param name="Number"></param>
        /// <returns></returns>
        public bool SetHeight(int Number)
        {

            bool temperature = false;
            //例如：高度80
            //26 32 31 30 39 35 E2 6D
            try
            {
                string positionStr = Number.ToString("D2");
                byte[] dataToSend = new byte[6];
                dataToSend[0] = 0x26;
                dataToSend[1] = 0x32;
                dataToSend[2] = 0x31;
                dataToSend[3] = 0x30;
                dataToSend[4] = (byte)positionStr[0];
                dataToSend[5] = (byte)positionStr[1];
                // 计算CRC16-Modbus
                ushort crc = CalculateCRC16Modbus(dataToSend);

                // 添加CRC到数据末尾
                byte[] commandWithCRC = new byte[dataToSend.Length + 2];
                Array.Copy(dataToSend, commandWithCRC, dataToSend.Length);
                commandWithCRC[dataToSend.Length] = (byte)(crc & 0xFF);
                commandWithCRC[dataToSend.Length + 1] = (byte)((crc >> 8) & 0xFF);

                byte[] byteRcv = session_.sendAndReadByteLock(commandWithCRC.ToArray(), 3000);
                //发送和接受参数一直代表设置成功
                if (commandWithCRC.SequenceEqual(byteRcv))
                {
                    temperature = true;
                }
                else
                {
                    temperature = false;
                }
            }
            catch (Exception ex)
            {

                throw;
            }

            return temperature;

        }


        /// <summary>
        /// 启动馏分收集器
        /// </summary>
        /// <param name="BeginNumber">开始试管</param>
        /// <param name="EndNumber">结束试管</param>
        /// <returns></returns>
        public bool StartOrStopOrPauseCollect(int Type)
        {

            bool temperature = false;

            //启动 26 31 30 30 30 31 a0 02
            //停止 26 31 30 30 30 30 61 c2
            //暂停 26 31 30 30 30 32 E0 03
            try
            {
                byte[] dataToSend = new byte[6];
                dataToSend[0] = 0x26;
                dataToSend[1] = 0x31;
                dataToSend[2] = 0x30;
                dataToSend[3] = 0x30;
                dataToSend[4] = 0x30;
                if (Type == 0)
                {
                    //停止
                    dataToSend[5] = 0x30;
                }
                if (Type == 1)
                {
                    //启动
                    dataToSend[5] = 0x31;
                }
                if (Type == 2)
                {
                    //暂停
                    dataToSend[5] = 0x32;
                }
                // 计算CRC16-Modbus
                ushort crc = CalculateCRC16Modbus(dataToSend);
                // 添加CRC到数据末尾
                byte[] commandWithCRC = new byte[dataToSend.Length + 2];
                Array.Copy(dataToSend, commandWithCRC, dataToSend.Length);
                commandWithCRC[dataToSend.Length] = (byte)(crc & 0xFF);
                commandWithCRC[dataToSend.Length + 1] = (byte)((crc >> 8) & 0xFF);
                byte[] byteRcv = session_.sendAndReadByteLock(commandWithCRC.ToArray(), 3000);
                if (byteRcv != null)
                {
                    //发送和接受参数一直代表设置成功
                    if (commandWithCRC.SequenceEqual(byteRcv))
                    {
                        temperature = true;
                    }
                    else
                    {
                        temperature = false;
                    }
                }
            }
            catch (Exception ex)
            {

                temperature = false;
            }

            return temperature;

        }



        /// <summary>
        /// 获取馏分运行状态  
        /// </summary>
        /// <returns></returns>
        public int GetCollectRunState()
        {

            int temperature = 3;


            try
            {

                //26 32 33 30 30 30 25 86

                byte[] returnbytes =
               {
            0x26, 0x32, 0x33, 0x30,0x30, 0x30, 0x25, 0x86
            };

                byte[] byteRcv = session_.sendAndReadByteLock(returnbytes.ToArray(), 3000);
                //返回
                //26 33 34 30 30 31 D8 F2    31 收集完成
                //26 33 34 30 30 30 XX XX    30  停止
                //26 33 34 30 30 32 XX XX    32  暂停
                //26 33 34 30 30 33 XX XX    33  收集中

                if (byteRcv != null && byteRcv.Length == 16)
                {
                    if (byteRcv[13] == 0x30)
                    {
                        temperature = 0;
                    }
                    if (byteRcv[13] == 0x31)
                    {
                        temperature = 1;
                    }
                    if (byteRcv[13] == 0x32)
                    {
                        temperature = 2;
                    }
                    if (byteRcv[13] == 0x33)
                    {
                        temperature = 3;
                    }
                }
            }
            catch (Exception ex)
            {

                throw;
            }

            return temperature;

        }



        /// <summary>
        /// 获取当前位置
        /// </summary>
        /// <returns></returns>
        public int GetPoLocation()
        {

            int temperature = 0;


            try
            {

                //26 32 32 30 30 30 24 7A

                byte[] returnbytes =
               {
            0x26, 0x32, 0x32, 0x30,0x30, 0x30, 0x24, 0x7A
            };

                byte[] byteRcv = session_.sendAndReadByteLock(returnbytes.ToArray(), 3000);
                //返回
                //26 33 30 30 30 30 18 02    30 30 代表位置0 

                if (byteRcv != null && byteRcv.Length == 16)
                {

                    char lastSecondChar = (char)byteRcv[12];
                    char lastChar = (char)byteRcv[13];
                    temperature = int.Parse($"{lastSecondChar}{lastChar}");

                }

                if (byteRcv != null && byteRcv.Length == 8)
                {

                    //发送和接受参数一直代表设置成功
                    if (returnbytes.SequenceEqual(byteRcv))
                    {
                        temperature = 0;
                    }
                    else
                    {
                        temperature = 0;
                    }
                }
            }
            catch (Exception ex)
            {

                throw;
            }

            return temperature;

        }


        /// <summary>
        /// 馏分清洗位置 清洗位置阀门常开
        /// </summary>
        /// <returns></returns>
        public bool CollectCleaning()
        {

            bool temperature = false;

            //右侧位置  清洗位置 26 31 39 30 31 33 23 CF
            try
            {
                byte[] dataToSend = new byte[6];
                dataToSend[0] = 0x26;
                dataToSend[1] = 0x31;
                dataToSend[2] = 0x39;
                dataToSend[3] = 0x30;
                dataToSend[4] = 0x31;
                dataToSend[5] = 0x33;
                // 计算CRC16-Modbus
                ushort crc = CalculateCRC16Modbus(dataToSend);
                // 添加CRC到数据末尾
                byte[] commandWithCRC = new byte[dataToSend.Length + 2];
                Array.Copy(dataToSend, commandWithCRC, dataToSend.Length);
                commandWithCRC[dataToSend.Length] = (byte)(crc & 0xFF);
                commandWithCRC[dataToSend.Length + 1] = (byte)((crc >> 8) & 0xFF);

                byte[] byteRcv = session_.sendAndReadByteLock(commandWithCRC.ToArray());
                if (byteRcv != null)
                {
                    temperature = true;
                }
            }
            catch (Exception ex)
            {

                throw;
            }

            return temperature;

        }

        /// <summary>
        /// 移动到左侧或者右侧
        /// </summary>
        /// <returns></returns>
        public bool MoveLeftOrRightLocation(int Type)
        {

            bool temperature = false;

            //右侧位置  清洗位置 26 31 39 30 31 33 23 CF
            //左侧位置  29号位置 26 31 36 30 30 30 61 4A
            try
            {
                byte[] dataToSend = new byte[6];
                if (Type == 0)
                {

                    dataToSend[0] = 0x26;
                    dataToSend[1] = 0x31;
                    dataToSend[2] = 0x39;
                    dataToSend[3] = 0x30;
                    dataToSend[4] = 0x31;
                    dataToSend[5] = 0x33;
                }
                else
                {
                    dataToSend[0] = 0x26;
                    dataToSend[1] = 0x31;
                    dataToSend[2] = 0x36;
                    dataToSend[3] = 0x30;
                    dataToSend[4] = 0x30;
                    dataToSend[5] = 0x30;
                }


                // 计算CRC16-Modbus
                ushort crc = CalculateCRC16Modbus(dataToSend);
                // 添加CRC到数据末尾
                byte[] commandWithCRC = new byte[dataToSend.Length + 2];
                Array.Copy(dataToSend, commandWithCRC, dataToSend.Length);
                commandWithCRC[dataToSend.Length] = (byte)(crc & 0xFF);
                commandWithCRC[dataToSend.Length + 1] = (byte)((crc >> 8) & 0xFF);

                byte[] byteRcv = session_.sendAndReadByteLock(commandWithCRC.ToArray());
                if (byteRcv != null)
                {
                    temperature = true;
                }
            }
            catch (Exception ex)
            {

                throw;
            }


            return temperature;

        }




        public static ushort CalculateCRC16Modbus(byte[] data)
        {
            ushort crc = 0xFFFF;
            for (int i = 0; i < data.Length; i++)
            {
                crc ^= data[i];
                for (int j = 0; j < 8; j++)
                {
                    bool lsb = (crc & 0x0001) != 0;
                    crc >>= 1;
                    if (lsb)
                        crc ^= 0xA001;
                }
            }
            return crc;
        }






        /// <summary>
        /// 发送指令测试通讯连接
        /// </summary>
        /// <param name="Number"></param>
        /// <returns></returns>
        public bool TestCon(int Number)
        {

            bool temperature = false;

            //例如：起始位置1
            //26 31 34 30 30 31  A1 32
            try
            {
                string positionStr = Number.ToString("D2");
                byte[] dataToSend = new byte[6];
                dataToSend[0] = 0x26;
                dataToSend[1] = 0x31;
                dataToSend[2] = 0x34;
                dataToSend[3] = 0x30;
                dataToSend[4] = (byte)positionStr[0];
                dataToSend[5] = (byte)positionStr[1];
                // 计算CRC16-Modbus
                ushort crc = CalculateCRC16Modbus(dataToSend);

                // 添加CRC到数据末尾
                byte[] commandWithCRC = new byte[dataToSend.Length + 2];
                Array.Copy(dataToSend, commandWithCRC, dataToSend.Length);
                commandWithCRC[dataToSend.Length] = (byte)(crc & 0xFF);
                commandWithCRC[dataToSend.Length + 1] = (byte)((crc >> 8) & 0xFF);

                byte[] byteRcv = session_.sendAndReadByteLock(commandWithCRC.ToArray(), 3000);
                if (byteRcv != null)
                {
                    //返回参数不为空代表通讯成功
                    temperature = true;
                }
            }
            catch (Exception ex)
            {

                temperature = false;
            }



            return temperature;

        }
    }
}
